package main

import (
	"fmt"
	"hash/crc32"
	"io"
	"log"
	"net/http"
	"os"
	"path"
	"strconv"

	requests "github.com/imroc/req"
)

type Block struct {
	w        http.ResponseWriter
	r        *http.Request
	basePath string
	target   string
}

func NewBlockHandle(w http.ResponseWriter, r *http.Request, target string) *Block {
	path, err := os.Getwd()
	if err != nil {
		log.Println(err)
		return nil
	}
	return &Block{
		w:        w,
		r:        r,
		basePath: path,
		target:   target,
	}

}
func (server *Block) Handle() {
	fmt.Println("blcok", server.target)
	crcname := crc32.ChecksumIEEE([]byte(server.target))
	crcnameStr := fmt.Sprint(crcname)
	childDirName := "cache/" + crcnameStr[:2]
	isDir := Exists(childDirName)
	if !isDir { //创建子文件夹
		errMk := os.Mkdir(childDirName, os.ModePerm)
		if errMk != nil {
			log.Println(errMk)
		}
	}
	cachefilepath := path.Join(server.basePath, "./cache", crcnameStr[:2], crcnameStr)
	_, err := os.Stat(cachefilepath)
	if err == nil { //存在缓存
		fileinfo, _ := os.Stat(cachefilepath)
		size := fileinfo.Size()

		// server.w.Header().Set("Connection", "keep-alive")
		// server.w.Header().Set("Accept-Ranges", "bytes")
		server.w.Header().Set("Cache-Control", "public, max-age=10368000")
		server.w.Header().Set("Content-Length", strconv.Itoa(int(size)))
		server.w.Header().Set("Expires", "Tue, 24 Mar 2050 15:58:58 GMT")
		server.w.Header().Set("Last-Modified", "Sat, 26 Oct 2010 13:08:37 GMT")
		contenttype, err := GetFileContentType(cachefilepath)
		server.PanicError(err)
		server.w.Header().Set("Content-Type", contenttype)
		server.w.WriteHeader(200) //修改状态码为200
		cachefile, err := os.Open(cachefilepath)
		defer cachefile.Close()
		server.PanicError(err)
		io.Copy(server.w, cachefile)
	} else {
		_r, err := requests.Get(server.target)
		server.PanicError(err)
		resp := _r.Response()
		defer func() {
			resp.Body.Close()
		}()
		if resp.StatusCode <= 210 && resp.StatusCode >= 200 {
			head := _r.Response().Header
			for k, _ := range head {
				if k != "Connection" && k != "Date" && k != "Etag" && k != "Content-Range" {
					server.w.Header().Set(k, head.Get(k))
				}
			}
			tempfilepath := path.Join(server.basePath, "./tmp", crcnameStr+".tmp")
			destFile, _ := os.OpenFile(tempfilepath, os.O_WRONLY|os.O_CREATE, 0777)
			w := io.MultiWriter(server.w, destFile)
			_, err = io.Copy(w, _r.Response().Body)
			// server.PanicError(err)
			defer os.Rename(tempfilepath, cachefilepath)
			defer destFile.Close()
		}
	}
}

func (this *Block) PanicError(err error) {
	if err != nil {
		panic(err)
	}
}
